from datetime import date, datetime
from django.shortcuts import render
from rest_framework.decorators import action
from rest_framework.generics import ListAPIView
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
from django_redis import get_redis_connection
from rest_framework_jwt.authentication import jwt_decode_handler

from question.models import *
from question.serializers import *
# Create your views here.
from django.db import transaction


class LabelsViewSet(ModelViewSet):
    '''所有标签列表用户　关注的标签　标签详情'''
    queryset = Label.objects.all()
    serializer_class = LabelSerializer

    @action(methods=['get'],detail=False)
    def users(self,request):
        # 用户关注的标签
        user = request.user
        labels = user.labels.all()
        serializer = LabelSerializer(instance=labels, many=True)
        return Response(serializer.data, status=200)

    # 更多标签
    @action(methods=['get'], detail=False)
    def full(self, request):
        labels = self.queryset.all()
        serializer = LabelSerializer(instance=labels, many=True)
        return Response(serializer.data, status=200)



    # 关注标签
    @action(methods=['put'], detail=True)
    def focusin(self, request, pk):
        user = request.user
        label = Label.objects.get(id=pk)
        label.users.add(user)
        return Response({
            'success': True,
            'message': '已关注'
        })



    # 取消关注标签
    @action(methods=['put'], detail=True)
    def focusout(self, request, pk):
        user = request.user
        label = Label.objects.get(id=pk)
        label.users.remove(user)
        return Response({
            'message': '取消关注',
            'success': True
        })


class NewQusetionsView(APIView):
    '''最新回答的问题'''
    def get(self, request, pk):
        if pk == '-1':
            # 获取全部标签的问题
            qusetions = Question.objects.all().order_by('-createtime')
            serializer = QuestionsSerializer(instance=qusetions, many=True)
        else:
            # 获取标签(id)对应的问题
            label = Label.objects.get(pk=pk)
            # 多对多取值
            qusetions = Question.objects.filter(labels=label).order_by('-createtime')
            serializer = QuestionsSerializer(instance=qusetions, many=True)
        return Response(serializer.data, status=200)


class HotQusetionsView(APIView):
    '''热门回答的问题'''
    def get(self, request, pk):
        if pk == '-1':
            # 获取全部标签的问题
            qusetions = Question.objects.all().order_by('-reply')
            serializer = QuestionsSerializer(instance=qusetions, many=True)
        else:
            # 获取标签(id)对应的问题
            label = Label.objects.get(pk=pk)
            # 多对多取值
            qusetions = Question.objects.filter(labels=label).order_by('-reply')
            serializer = QuestionsSerializer(instance=qusetions, many=True)
        return Response(serializer.data, status=200)


class WaitQusetionsView(APIView):
    '''等待回答的问题'''
    def get(self, request, pk):
        if pk == '-1':
            # 获取全部标签的问题
            qusetions = Question.objects.filter(reply=0)
            serializer = QuestionsSerializer(instance=qusetions, many=True)
        else:
            # 获取标签(id)对应的问题
            label = Label.objects.get(pk=pk)
            # 对多取值
            qusetions = Question.objects.filter(labels=label).filter(reply=0)
            serializer = QuestionsSerializer(instance=qusetions, many=True)
        return Response(serializer.data, status=200)


class QuestionsViewSet(ModelViewSet):
    '''问题'''
    queryset = Question.objects.all()
    serializer_class = QuestionsSerializer

    # 发布问题
    def create(self, request, *args, **kwargs):
        # 重写create方法,实现新建保存中间表信息
        content = request.data['content']
        title = request.data['title']
        labels = request.data['labels']

        # 添加事务
        with transaction.atomic():
            save_id = transaction.savepoint()  # 创建保存点
            question = Question.objects.create(content=content, title=title, user_id=request.user.id)
            for label in labels:
                question.labels.add(label)  # 插入问题和标签中间表
            transaction.savepoint_commit(save_id)  # 取消创建的保存点
        return Response({'message': '发布成功', 'success': True})

    # 问题详情
    def retrieve(self, request, *args, **kwargs):

        question = self.queryset.get(id=(self.kwargs['pk']))
        question.visits += 1  # 增加浏览量
        question.save()
        # 获取问题对应的评论或回答的内容
        rs = question.replies.all()
        question.comment_question = []  # 问题评论列表
        question.answer_question = []  # 回答问题列表
        for r in rs:
            if r.type == 0:
                question.comment_question.append(r)
            elif r.type == 2:
                question.answer_question.append(r)

        serializer = QuestionsDetailSerializer(question)

        return Response(serializer.data, status=200)

    # 问题有用
    @action(methods=['put'], detail=True)
    def useful(self,request, pk):
        conn = get_redis_connection('verify_code')
        q_ful = conn.get('q_useful_%s_%s' % (pk, request.user.id))
        if q_ful is None:

            question = self.queryset.get(id=pk)
            question.useful_count += 1
            if question.unuseful_count > 0:
                question.unuseful_count -= 1
            question.save()

            conn.setex('q_useful_%s_%s' % (pk, request.user.id), 3600, 1)
        else:
            return Response({'message': '请勿频繁操作!', 'success': False})

        return Response({'message': 'ok', 'success': True})

    # 问题没用
    @action(methods=['put'], detail=True)
    def unuseful(self,request, pk):
        conn = get_redis_connection('verify_code')
        q_ful = conn.get('q_unuseful_%s_%s' % (pk, request.user.id))
        if q_ful is None:

            question = self.queryset.get(id=pk)
            question.unuseful_count += 1
            if question.useful_count > 0:
                question.useful_count -= 1
            question.save()

            conn.setex('q_unuseful_%s_%s' % (pk, request.user.id), 3600, 1)
        else:
            return Response({'message': '请勿频繁操作!', 'success': False})

        return Response({'message': 'ok', 'success': True})


class ReplyViewSet(ModelViewSet):
    '''回答问题'''
    queryset = Reply.objects.all()
    serializer_class = ReplySerializer

    def create(self, request, *args, **kwargs):

        request.data['user_id'] = request.user.id
        user = User.objects.get(id=request.user.id)
        # print(request.data)
        # 添加事务
        with transaction.atomic():
            save_id = transaction.savepoint()  # 创建保存点
            serializer = self.serializer_class(data=request.data)
            serializer.is_valid(raise_exception=True)
            serializer.save()

            question = Question.objects.get(id=request.data['problem'])

            question.replyname = user.username
            question.replytime = datetime.now()
            question.reply += 1
            question.save()

            transaction.savepoint_commit(save_id)   # 取消创建的保存点

        return Response({'message': 'ok', 'success': True})



    # @action(methods=['put'], detail=True)
    # def useful(self, request, pk):
    #     reply = self.queryset.get(id=pk)
    #     reply.useful_count += 1
    #     if reply.unuseful_count > 0:
    #         reply.unuseful_count -= 1
    #     reply.save()
    #     return Response({'message': 'ok', 'success': True})
    #
    #
    # @action(methods=['put'], detail=True)
    # def unuseful(self, request, pk):
    #     reply = self.queryset.get(id=pk)
    #     reply.unuseful_count += 1
    #     if reply.useful_count > 0:
    #         reply.useful_count -= 1
    #     reply.save()
    #     return Response({'message': 'ok', 'success': True})


class ReplyUsefulAPIView(APIView):
    '''回答有用'''
    def put(self, request, pk):
        conn = get_redis_connection('verify_code')
        r_code = conn.get('r_useful_%s_%s' % (pk, request.user.id))
        if r_code:
            return Response({'message': '请勿频繁操作!', 'success': False})

        reply = Reply.objects.get(pk=pk)
        reply.useful_count = reply.useful_count + 1
        reply.save()
        conn.setex('r_useful_%s_%s' % (pk, request.user.id), 3600, 1)

        return Response({'message':'回答有用','success':True})


class ReplyUnusefulAPIView(APIView):
    '''回答无用'''
    def put(self, request, pk):
        conn = get_redis_connection('verify_code')
        r_code = conn.get('r_unuseful_%s_%s' % (pk, request.user.id))
        if r_code:
            return Response({'message': '请勿频繁操作!', 'success': False})

        reply = Reply.objects.get(pk=pk)
        reply.unuseful_count = reply.unuseful_count + 1
        if reply.useful_count > 0:
            reply.useful_count -= 1
        reply.save()
        conn.setex('r_unuseful_%s_%s' % (pk, request.user.id), 3600, 1)

        return Response({'message':'回答无用','success':True})
